
package com.ukefu.webim.web.interceptor;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.boot.autoconfigure.web.BasicErrorController;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.ukefu.core.UKDataContext;
import com.ukefu.util.Menu;
import com.ukefu.util.UKTools;
import com.ukefu.util.callout.CallOutUtils;
import com.ukefu.webim.service.acd.ServiceQuene;
import com.ukefu.webim.service.cache.CacheHelper;
import com.ukefu.webim.service.repository.OrganRepository;
import com.ukefu.webim.service.repository.OrganRoleRepository;
import com.ukefu.webim.service.repository.RoleAuthRepository;
import com.ukefu.webim.service.repository.TenantRepository;
import com.ukefu.webim.service.repository.UserRepository;
import com.ukefu.webim.service.repository.UserRoleRepository;
import com.ukefu.webim.util.HttpClientUtil;
import com.ukefu.webim.web.model.CallOutConfig;
import com.ukefu.webim.web.model.Organ;
import com.ukefu.webim.web.model.OrganRole;
import com.ukefu.webim.web.model.Role;
import com.ukefu.webim.web.model.RoleAuth;
import com.ukefu.webim.web.model.SystemConfig;
import com.ukefu.webim.web.model.Tenant;
import com.ukefu.webim.web.model.UKeFuDic;
import com.ukefu.webim.web.model.UKeFuValue;
import com.ukefu.webim.web.model.User;
import com.ukefu.webim.web.model.UserRole;

public class UserInterceptorHandler extends HandlerInterceptorAdapter {
	
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
    	boolean filter = false; 
        User user = (User) request.getSession(true).getAttribute(UKDataContext.USER_SESSION_NAME) ;
        if(handler instanceof HandlerMethod) {
	        HandlerMethod  handlerMethod = (HandlerMethod ) handler ;
	        Menu menu = handlerMethod.getMethod().getAnnotation(Menu.class) ;
	        if(user != null || (menu!=null && menu.access()) || handlerMethod.getBean() instanceof BasicErrorController){
	        	filter = true;
	        }
	        if(menu != null && ((user!=null && menu.spadmin() == true && user.isSuperuser() == false) || (user!=null && menu.admin() == true && !"0".equals(user.getUsertype())))) {
	        	filter = false ;
	        }
	        if (user==null) {
	        	SystemConfig systemConfig = UKTools.getSystemConfig();
	        	if (systemConfig.isEnablessocheck()) {
	        		if (request.getParameter("token") != null && !StringUtils.isBlank(request.getParameter("token").toString())) {
	        			String token = request.getParameter("token").toString();
	        			if (user == null && !StringUtils.isBlank(systemConfig.getSsocheckurl())) {
	        				String result = HttpClientUtil.doGet(systemConfig.getSsocheckurl().replace("{token}", request.getParameter("token").toString()));
	        				if (!StringUtils.isBlank(result) && result.indexOf("data") >=0) {
	        					@SuppressWarnings("unchecked")
	        					Map<String, Object> map = UKTools.toObject(result,Map.class);
	        					if (map != null && map.get("data")!=null && !StringUtils.isBlank(map.get("data").toString())) {
	        						User loginuser = UKDataContext.getContext().getBean(UserRepository.class).findByUsernameAndDatastatus(map.get("data").toString(), false);
	        						if (loginuser != null && processLogin(request, response, loginuser)) {
	        							response.sendRedirect("/");
	        							request.getSession(true).setAttribute("Utoken", token);
	        							filter = true;
	        						}
	        					}
	        				}
	        			}
	        		}
	        	}
			}
	        if(!filter){
	        	response.sendRedirect("/login.html");
	        }
        }else {
        	filter =true ;
        }
        return filter ; 
    }

    @SuppressWarnings("unchecked")
	public void postHandle(HttpServletRequest arg0, HttpServletResponse response, Object arg2,
            ModelAndView view) throws Exception {
    	User user = (User) arg0.getSession().getAttribute(UKDataContext.USER_SESSION_NAME) ;
    	String infoace = (String) arg0.getSession().getAttribute(UKDataContext.UKEFU_SYSTEM_INFOACQ) ;		//进入信息采集模式
    	SystemConfig systemConfig = UKTools.getSystemConfig();
    	if( view!=null){
			if(systemConfig != null){
				view.addObject("systemConfig", systemConfig)  ;
			}else{
				view.addObject("systemConfig", new SystemConfig())  ;
			}
	    	if(user!=null){
				view.addObject("user", user) ;

				if(systemConfig!=null&&systemConfig.isEnabletneant() &&  user.isSuperuser()) {
					view.addObject("callcentershowall", true) ;
				}

				if(systemConfig!=null&&systemConfig.isEnabletneant()) {
					view.addObject("enabletneant", true) ;
				}

				if(systemConfig!=null && systemConfig.isEnablessl()) {
					view.addObject("schema","https") ;
					if(arg0.getServerPort() == 80) {
						view.addObject("port", 443) ;
					}else {
						view.addObject("port", arg0.getServerPort()) ;
					}
				}else {
					view.addObject("schema",arg0.getScheme()) ;
					view.addObject("port",arg0.getServerPort()) ;
				}
				view.addObject("hostname",arg0.getServerName()) ;
				
				HandlerMethod  handlerMethod = (HandlerMethod ) arg2 ;
				Menu menu = handlerMethod.getMethod().getAnnotation(Menu.class) ;
				if(menu!=null){
					view.addObject("subtype", menu.subtype()) ;
					view.addObject("maintype", menu.type()) ;
					view.addObject("typename", menu.name()) ;
				}
				view.addObject("orgi", user.getOrgi()) ;


				CallOutConfig callOutConfig = CallOutUtils.initCallOutConfig(user.getOrgi()) ;
				view.addObject("callOutConfig",callOutConfig);

			}
	    	if(!StringUtils.isBlank(infoace)){
	    		view.addObject("infoace", infoace) ;		//进入信息采集模式
	    	}
	    	view.addObject("webimport",UKDataContext.getWebIMPort()) ;
	    	view.addObject("sessionid", UKTools.getContextID(arg0.getSession().getId())) ;

	    	if(user == null){
				//view.addObject("models", UKDataContext.model) ;
			}else{
				Map<String , Boolean> modelMap = UKDataContext.orgiModel.get(user.getOrgi());
				if(modelMap == null || modelMap.size() == 0){
					if(UKDataContext.SYSTEM_ORGI.equals(user.getOrgi())){
						modelMap = UKDataContext.model;
					}else{
						modelMap = new HashMap<>();
					}
				}
				view.addObject("models", modelMap) ;
			}

	    	if(user!=null){
	    		view.addObject("agentStatusReport",ServiceQuene.getReport(user.getOrgi())) ;
	    	}
			/**
			 * WebIM共享用户
			 */
			User imUser = (User) arg0.getSession().getAttribute(UKDataContext.IM_USER_SESSION_NAME) ;
			if(imUser == null && view!=null){
				imUser = new User();
				imUser.setUsername(UKDataContext.GUEST_USER) ;
				imUser.setId(UKTools.getContextID(arg0.getSession(true).getId())) ;
				imUser.setSessionid(imUser.getId()) ;
				view.addObject("imuser", imUser) ;
			}
			
			if(arg0.getParameter("msg") != null){
				view.addObject("msg", arg0.getParameter("msg")) ;
			}
			view.addObject("uKeFuDic", UKeFuDic.getInstance()) ;	//处理系统 字典数据 ， 通过 字典code 获取
			
			view.addObject("uKeFuValue", UKeFuValue.getInstance()) ;	//处理系统 字典数据 ， 通过 字典code 获取
			
			
			
			view.addObject("uKeFuSecField", CacheHelper.getSystemCacheBean().getCacheObject(UKDataContext.UKEFU_SYSTEM_SECFIELD, UKDataContext.SYSTEM_ORGI)) ;	//处理系统 需要隐藏号码的字段， 启动的时候加载

			view.addObject("tagTypeList", UKeFuDic.getInstance().getDic("com.dic.tag.type")) ;
	    	
			view.addObject("advTypeList", UKeFuDic.getInstance().getDic("com.dic.adv.type")) ;
			view.addObject("searchList",UKeFuDic.getInstance().getDic("com.callout.name.search"));
			view.addObject("sessionType",UKeFuDic.getInstance().getDic("com.dic.session.type"));
			view.addObject("smsTempletTypeList",UKeFuDic.getInstance().getDic("com.dic.sms.templetype"));
			view.addObject("bussOpList",UKeFuDic.getInstance().getDic("com.dic.xiaoe.input"));
			view.addObject("bussExecList",UKeFuDic.getInstance().getDic("com.dic.xiaoe.bussop"));
			view.addObject("bussTypeList",UKeFuDic.getInstance().getDic("com.dic.xiaoe.busstype"));
			
			view.addObject("entityTypeList",UKeFuDic.getInstance().getDic("com.dic.xiaoe.entity"));
			
 			view.addObject("ip", arg0.getRemoteAddr()) ;
 			
 			view.addObject("statusList",UKeFuDic.getInstance().getDic("com.dic.callout.activity"));
 			
 			/**
 			 * CRM参数
 			 */
 			NativeWebRequest webRequest = new ServletWebRequest(arg0);
 			Map<String, String> map = (Map<String, String>) webRequest.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST);
 		    if(map.get("crm_code")!=null) {
		    	view.addObject("crm_code", map.get("crm_code")) ;
		    }
 		    
 		    /**
 		     * 	名单管理-其他活动 活动类型参数
 		     */
 		    if(map.get("acttype")!=null) {
		    	view.addObject("acttype", map.get("acttype")) ;
		    }
    	}
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
    }

    
    public boolean processLogin(HttpServletRequest request, HttpServletResponse response ,final User loginUser ) {
    	boolean success = false;
    	if(loginUser!=null) {
	    	loginUser.setLogin(true);
	    	//登录成功 判断是否进入多租户页面
	    	SystemConfig systemConfig = UKTools.getSystemConfig();
	    	//开启多租户 判断多租户是否锁定
			if(systemConfig!=null&&systemConfig.isEnabletneant()) {
				Tenant tenant = UKDataContext.getContext().getBean(TenantRepository.class).findByTenantcode(loginUser.getOrgi());
				if((tenant == null || (tenant != null && tenant.isDatastatus())) && !UKDataContext.SYSTEM_ORGI.equals(loginUser.getOrgi())){
					return false;
				}
			}

	    	if(systemConfig!=null&&systemConfig.isEnabletneant() && systemConfig.isTenantconsole() &&!loginUser.isSuperuser()) {
	    		return false;
	    	}
	    	List<UserRole> userRoleList = UKDataContext.getContext().getBean(UserRoleRepository.class).findByOrgiAndUser(loginUser.getOrgi(), loginUser);
	    	if(userRoleList!=null && userRoleList.size()>0){
	    		for(UserRole userRole : userRoleList){
	    			loginUser.getRoleList().add(userRole.getRole()) ;
	    		}
	    	}
	    	if(!StringUtils.isBlank(loginUser.getOrgan())){
	    		Organ organ = UKDataContext.getContext().getBean(OrganRepository.class).findByIdAndOrgi(loginUser.getOrgan(), loginUser.getOrgi()) ;
	    		if(organ!=null){
	    			List<OrganRole> organRoleList = UKDataContext.getContext().getBean(OrganRoleRepository.class).findByOrgiAndOrgan(loginUser.getOrgi(), organ) ;
	    			if(organRoleList.size() > 0){
	    				for(OrganRole organRole : organRoleList){
	    					loginUser.getRoleAuthMap().put(organRole.getDicvalue(),true);
	    				}
	    			}
	    		}
	    	}
	    	//获取用户的授权资源
	    	List<RoleAuth> roleAuthList = UKDataContext.getContext().getBean(RoleAuthRepository.class).findAll(new Specification<RoleAuth>(){
	    		@Override
	    		public Predicate toPredicate(Root<RoleAuth> root, CriteriaQuery<?> query,
	    				CriteriaBuilder cb) {
	    			List<Predicate> list = new ArrayList<Predicate>();  
	    			if(loginUser.getRoleList()!=null && loginUser.getRoleList().size() > 0){
	    				for(Role role : loginUser.getRoleList()){
	    					list.add(cb.equal(root.get("roleid").as(String.class), role.getId())) ;
	    				}
	    			}
	    			Predicate[] p = new Predicate[list.size()];  
	    			cb.and(cb.equal(root.get("orgi").as(String.class), loginUser.getOrgi())) ;
	    			return cb.or(list.toArray(p));  
	    		}}) ;
	    	if(roleAuthList!=null) {
	    		for(RoleAuth roleAuth:roleAuthList) {
	    			loginUser.getRoleAuthMap().put(roleAuth.getDicvalue(), true);
	    		}
	    	}
	
	    	loginUser.setLastlogintime(new Date());
	    	if(!StringUtils.isBlank(loginUser.getId())){
	    		UKDataContext.getContext().getBean(UserRepository.class).save(loginUser) ;
	    	}
	    	request.getSession(true).removeAttribute(UKDataContext.USER_SESSION_NAME) ;
			request.getSession(true).setAttribute(UKDataContext.USER_SESSION_NAME , loginUser) ;
			loginUser.setHttpsession(request.getSession().getId());
			UKDataContext.users.put(request.getSession().getId(), loginUser) ;
			UKDataContext.sessions.put(request.getSession().getId(), request.getSession()) ;
			success = true;
	    	//当前用户 企业id为空 调到创建企业页面
        	if(StringUtils.isBlank(loginUser.getOrgid())) {
        		return false;
        	}
    	}
    	return success ;
    }
}